<template>
  <div class="navigation-container">
    <div class="navigation-header">
      <div class="header-actions">
        <el-button type="primary" plain size="small" @click="goBack">
          <el-icon><Back /></el-icon> 返回首页
        </el-button>
      </div>
      <h1>保护区景点导航</h1>
      <p>使用高德地图API进行保护区景点之间的导航</p>
    </div>

    <!-- 主要内容区域 -->
    <el-row :gutter="20">
      <!-- 左侧地图区域 -->
      <el-col :span="16">
        <el-card class="map-card">
          <div id="scenicMapView" class="map-container"></div>
        </el-card>
      </el-col>

      <!-- 右侧功能区域 -->
      <el-col :span="8">
        <!-- 景区选择 -->
        <el-card class="area-select-card">
          <template #header>
            <div class="card-header">
              <span>景区选择</span>
            </div>
          </template>

          <div class="area-tabs">
            <el-tabs v-model="activeArea" @tab-click="handleAreaChange">
              <el-tab-pane label="胶南灵山岛保护区" name="erdihu"></el-tab-pane>
              <el-tab-pane label="大公岛保护区" name="yunmen"></el-tab-pane>
              <el-tab-pane label="大泽山保护区" name="bailang"></el-tab-pane>
              <el-tab-pane label="崂山保护区" name="xiashan"></el-tab-pane>
              <el-tab-pane label="胶州艾山保护区" name="binhai"></el-tab-pane>
              <el-tab-pane label="马山保护区" name="mihe"></el-tab-pane>
            </el-tabs>
          </div>
        </el-card>

        <!-- 导航设置 -->
        <el-card class="navigation-card">
          <template #header>
            <div class="card-header">
              <span>导航设置</span>
            </div>
          </template>

          <el-form label-position="top">
            <el-form-item label="起点">
              <el-select
                v-model="startPoint"
                filterable
                placeholder="选择起点"
                style="width: 100%"
                @change="handleStartPointChange"
              >
                <el-option
                  v-for="point in filteredScenicPoints"
                  :key="point.attributes.OBJECTID"
                  :label="point.attributes.ScenicName"
                  :value="point.attributes.OBJECTID"
                ></el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="终点">
              <el-select
                v-model="endPoint"
                filterable
                placeholder="选择终点"
                style="width: 100%"
                @change="handleEndPointChange"
              >
                <el-option
                  v-for="point in filteredScenicPoints"
                  :key="point.attributes.OBJECTID"
                  :label="point.attributes.ScenicName"
                  :value="point.attributes.OBJECTID"
                ></el-option>
              </el-select>
            </el-form-item>

            <el-form-item>
              <el-button
                type="primary"
                @click="calculateRoute"
                :disabled="!startPoint || !endPoint"
                style="width: 100%"
              >
                <el-icon><Location /></el-icon> 计算路线
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>

        <!-- 路线信息 -->
        <el-card class="route-info-card" v-if="routeInfo">
          <template #header>
            <div class="card-header">
              <span>路线信息</span>
            </div>
          </template>

          <div class="route-summary">
            <div class="route-item">
              <div class="route-label">总距离</div>
              <div class="route-value">{{ formatDistance(routeInfo.distance) }}</div>
            </div>
            <div class="route-item">
              <div class="route-label">预计时间</div>
              <div class="route-value">{{ formatDuration(routeInfo.duration) }}</div>
            </div>
          </div>

          <div class="route-steps">
            <h4>导航指引</h4>
            <el-timeline>
              <el-timeline-item
                v-for="(step, index) in routeInfo.steps"
                :key="index"
                :type="getStepType(step)"
                :color="getStepColor(step)"
              >
                <p class="step-instruction">{{ step.instruction }}</p>
                <p class="step-distance">{{ formatDistance(step.distance) }}</p>
              </el-timeline-item>
            </el-timeline>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
declare global {
  interface Window {
    _tempFeatures: __esri.Graphic[]
  }
}
import { ref, onMounted, computed, watch } from 'vue'
import { Back, Location } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'
import Graphic from '@arcgis/core/Graphic'
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol'
import SimpleLineSymbol from '@arcgis/core/symbols/SimpleLineSymbol'
import Polyline from '@arcgis/core/geometry/Polyline'
import { gaodeImageLayer } from '@/utils/GaoDeBaseLayer'
import { getGaoDeRoute, type Step } from '@/utils/gaodeAPI'

// 路由
const router = useRouter()

// 地图和图层
let view: __esri.MapView
let featureLayer: __esri.FeatureLayer

// 状态变量
const loading = ref(false)
const activeArea = ref('erdihu') // 默认胶南灵山岛保护区
const allScenicPoints = ref<any[]>([])
const startPoint = ref<number | null>(null)
const endPoint = ref<number | null>(null)
const routeInfo = ref<{
  distance: string
  duration: string
  steps: Step[]
} | null>(null)

// 各个景区的中心坐标
const areaCenters = {
  erdihu: [120.179558,35.765965], // 胶南灵山岛坐标
  yunmen: [120.503415,35.967122], // 大公岛坐标
  bailang: [120.022251,37.00615], // 大泽山坐标
  xiashan: [120.605305,36.198964], // 崂山坐标
  binhai: [119.93718,36.121442], // 胶州艾山坐标
  mihe: [120.651138,36.340289] // 马山坐标
}

// 根据当前选中的景区过滤景点
const filteredScenicPoints = computed(() => {
  return allScenicPoints.value.filter((point) => {
    const areaName = getCurrentAreaName()
    return point.attributes.OwnerScenic === areaName
  })
})

// 初始化地图
const initMap = async () => {
  // 创建地图实例，使用影像图层
  const map = new Map({
    basemap: {
      baseLayers: [gaodeImageLayer],
    },
  })

  // 创建地图视图
  view = new MapView({
    container: 'scenicMapView',
    map: map,
    center: areaCenters[activeArea.value as keyof typeof areaCenters], // 根据当前选中的景区设置中心点
    zoom: 15,
    popup: {
      dockEnabled: true,
      dockOptions: {
        buttonEnabled: false,
        breakpoint: false,
      },
    },
  })

  // 创建要素图层
  featureLayer = new FeatureLayer({
    url: 'https://services8.arcgis.com/hvBaJk0FLVU4yP47/arcgis/rest/services/ScenicPointLayer/FeatureServer/0',
    outFields: ['*'],
    popupEnabled: false,
    renderer: {
      type: 'unique-value',
      field: 'ScenicType',
      defaultSymbol: {
        type: 'simple-marker',
        size: 14,
        color: [156, 156, 156, 0.8], // 默认灰色
        outline: {
          color: [255, 255, 255],
          width: 2,
        },
      },
      uniqueValueInfos: [
        {
          value: '自然风光',
          symbol: {
            type: 'simple-marker',
            size: 14,
            color: [56, 168, 0, 0.8], // 绿色
            outline: {
              color: [255, 255, 255],
              width: 2,
            },
          },
        },
        {
          value: '历史文化',
          symbol: {
            type: 'simple-marker',
            size: 14,
            color: [225, 76, 66, 0.8], // 红色
            outline: {
              color: [255, 255, 255],
              width: 2,
            },
          },
        },
        {
          value: '休闲娱乐',
          symbol: {
            type: 'simple-marker',
            size: 14,
            color: [0, 112, 255, 0.8], // 蓝色
            outline: {
              color: [255, 255, 255],
              width: 2,
            },
          },
        },
      ],
    },
    // 添加标注
    labelingInfo: [
      {
        symbol: {
          type: 'text',
          color: '#333333',
          haloColor: '#ffffff',
          haloSize: 2,
          font: {
            size: 12,
            weight: 'normal',
          },
        },
        labelPlacement: 'above-center',
        labelExpressionInfo: {
          expression: '$feature.ScenicName',
        },
        minScale: 5000, // 当地图缩放到多少比例尺以内才显示标签
        maxScale: 0,
      },
    ],
  })

  // 将图层添加到地图
  map.add(featureLayer)

  // 加载要素数据
  await queryFeatures()
}

// 查询景点数据
const queryFeatures = async () => {
  if (!featureLayer) return

  loading.value = true
  try {
    // 创建查询
    const query = featureLayer.createQuery()
    query.where = '1=1' // 查询所有数据
    query.outFields = ['*']

    // 执行查询
    const result = await featureLayer.queryFeatures(query)

    // 存储原始的ESRI要素对象到非响应式变量中
    window._tempFeatures = result.features

    // 将要素数据存储到响应式变量中
    allScenicPoints.value = result.features.map((feature, index) => ({
      _index: index,
      attributes: { ...feature.attributes },
      geometryInfo: feature.geometry
        ? {
            x: feature.geometry.type === 'point' ? (feature.geometry as __esri.Point).x : null,
            y: feature.geometry.type === 'point' ? (feature.geometry as __esri.Point).y : null,
            type: feature.geometry.type,
          }
        : null,
    }))
  } catch (error) {
    console.error('查询景点数据失败', error)
    allScenicPoints.value = []
  } finally {
    loading.value = false
  }
}

// 获取当前景区名称
const getCurrentAreaName = () => {
  switch (activeArea.value) {
    case 'erdihu':
      return '胶南灵山岛保护区'
    case 'yunmen':
      return '大公岛保护区'
    case 'bailang':
      return '大泽山保护区'
    case 'xiashan':
      return '崂山保护区'
    case 'binhai':
      return '胶州艾山保护区'
    case 'mihe':
      return '马山保护区'
    default:
      return ''
  }
}

// 处理景区切换
const handleAreaChange = () => {
  // 将地图中心移动到选中的景区
  view?.goTo({
    center: areaCenters[activeArea.value as keyof typeof areaCenters],
    zoom: 15,
  })

  // 清空选择和路线
  startPoint.value = null
  endPoint.value = null
  routeInfo.value = null
  clearRouteGraphics()
}

// 处理起点变化
const handleStartPointChange = () => {
  if (startPoint.value) {
    highlightPoint(startPoint.value, 'start')
  }
}

// 处理终点变化
const handleEndPointChange = () => {
  if (endPoint.value) {
    highlightPoint(endPoint.value, 'end')
  }
}

// 高亮显示点
const highlightPoint = (objectId: number, type: 'start' | 'end') => {
  // 查找对应的要素
  const feature = window._tempFeatures?.find((f) => f.attributes.OBJECTID === objectId)
  if (!feature || !feature.geometry) return

  // 清除之前的高亮
  clearPointGraphics(type)

  // 创建高亮符号
  const highlightSymbol = new SimpleMarkerSymbol({
    color: type === 'start' ? [0, 255, 0, 0.8] : [255, 0, 0, 0.8], // 起点绿色，终点红色
    size: 16,
    outline: {
      color: [255, 255, 255],
      width: 2,
    },
  })

  // 创建高亮图形
  const highlightGraphic = new Graphic({
    geometry: feature.geometry,
    symbol: highlightSymbol,
    attributes: {
      type: type, // 添加类型属性，用于后续识别
    },
  })

  // 添加到地图
  view?.graphics.add(highlightGraphic)

  // 将视图中心移动到要素位置
  view?.goTo({
    target: feature.geometry,
    zoom: 15,
  })
}

// 清除点图形
const clearPointGraphics = (type?: 'start' | 'end') => {
  if (!view) return

  if (type) {
    // 只清除指定类型的点
    const graphicsToRemove = view.graphics.filter((g) => g.attributes?.type === type)
    graphicsToRemove.forEach((g) => view.graphics.remove(g))
  } else {
    // 清除所有点
    const graphicsToRemove = view.graphics.filter(
      (g) => g.attributes?.type === 'start' || g.attributes?.type === 'end',
    )
    graphicsToRemove.forEach((g) => view.graphics.remove(g))
  }
}

// 清除路线图形
const clearRouteGraphics = () => {
  if (!view) return

  // 清除路线
  const graphicsToRemove = view.graphics.filter((g) => g.attributes?.type === 'route')
  graphicsToRemove.forEach((g) => view.graphics.remove(g))
}

// 计算路线
const calculateRoute = async () => {
  if (!startPoint.value || !endPoint.value) {
    ElMessage.warning('请选择起点和终点')
    return
  }

  loading.value = true
  try {
    // 查找起点和终点的要素
    const startFeature = window._tempFeatures?.find(
      (f) => f.attributes.OBJECTID === startPoint.value,
    )
    const endFeature = window._tempFeatures?.find((f) => f.attributes.OBJECTID === endPoint.value)

    if (!startFeature || !endFeature || !startFeature.geometry || !endFeature.geometry) {
      ElMessage.error('无法获取起点或终点的位置信息')
      return
    }

    // 获取起点和终点的坐标
    const startGeometry = startFeature.geometry as __esri.Point
    const endGeometry = endFeature.geometry as __esri.Point

    // 调用高德地图API获取路线
    const startCoord = `${startGeometry.longitude},${startGeometry.latitude}`
    const endCoord = `${endGeometry.longitude},${endGeometry.latitude}`

    const routeResponse = await getGaoDeRoute(startCoord, endCoord)

    if (routeResponse.status === '1' && routeResponse.route.paths.length > 0) {
      const path = routeResponse.route.paths[0]

      // 保存路线信息
      routeInfo.value = {
        distance: path.distance,
        duration: path.duration,
        steps: path.steps,
      }

      // 绘制路线
      drawRoute(path.steps)
    } else {
      ElMessage.error('获取路线失败: ' + routeResponse.info)
    }
  } catch (error) {
    console.error('计算路线失败', error)
    ElMessage.error('计算路线失败')
  } finally {
    loading.value = false
  }
}

// 绘制路线
const drawRoute = (steps: Step[]) => {
  // 清除之前的路线
  clearRouteGraphics()

  // 解析所有步骤的坐标点
  const allPoints: number[][] = []

  steps.forEach((step) => {
    const polylineStr = step.polyline
    const pointPairs = polylineStr.split(';')

    pointPairs.forEach((pair) => {
      const coords = pair.split(',')
      if (coords.length === 2) {
        allPoints.push([parseFloat(coords[0]), parseFloat(coords[1])])
      }
    })
  })

  if (allPoints.length > 0) {
    // 创建路线几何体
    const polyline = new Polyline({
      paths: [allPoints],
    })

    // 创建路线符号
    const lineSymbol = new SimpleLineSymbol({
      color: [0, 122, 194, 0.8],
      width: 4,
      style: 'solid',
    })

    // 创建路线图形
    const routeGraphic = new Graphic({
      geometry: polyline,
      symbol: lineSymbol,
      attributes: {
        type: 'route',
      },
    })

    // 添加到地图
    view?.graphics.add(routeGraphic)

    // 调整视图以显示整个路线
    view?.goTo({
      target: polyline.extent!.expand(1.5),
    })
  }
}

// 格式化距离
const formatDistance = (distance: string) => {
  const dist = parseInt(distance, 10)
  if (dist >= 1000) {
    return `${(dist / 1000).toFixed(1)} 公里`
  }
  return `${dist} 米`
}

// 格式化时间
const formatDuration = (duration: string) => {
  const time = parseInt(duration, 10)
  if (time >= 3600) {
    const hours = Math.floor(time / 3600)
    const minutes = Math.floor((time % 3600) / 60)
    return `${hours} 小时 ${minutes} 分钟`
  } else if (time >= 60) {
    const minutes = Math.floor(time / 60)
    return `${minutes} 分钟`
  }
  return `${time} 秒`
}

// 获取步骤类型
const getStepType = (step: Step) => {
  if (step.action === '到达目的地') {
    return 'success'
  }
  return 'primary'
}

// 获取步骤颜色
const getStepColor = (step: Step) => {
  if (step.action === '到达目的地') {
    return '#67c23a'
  }
  return '#409eff'
}

// 返回首页
const goBack = () => {
  router.push('/')
}

// 监听起点和终点变化
watch([startPoint, endPoint], () => {
  // 如果起点和终点都有值，但不相同，则清除路线
  if (startPoint.value && endPoint.value && startPoint.value !== endPoint.value) {
    clearRouteGraphics()
    routeInfo.value = null
  }
})

// 页面加载完成后初始化地图
onMounted(() => {
  initMap()
})
</script>

<style scoped lang="scss">
.navigation-container {
  padding: 20px;
}

.navigation-header {
  margin-bottom: 20px;
  background-color: #fff;
  padding: 15px 20px;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-left: 4px solid #409eff;
}

.header-actions {
  margin-bottom: 15px;
}

.navigation-header h1 {
  font-size: 24px;
  color: #303133;
  margin-bottom: 8px;
}

.navigation-header p {
  color: #606266;
  font-size: 14px;
}

.map-container {
  height: 500px;
  width: 100%;
  position: relative;
}

.map-card,
.area-select-card,
.navigation-card,
.route-info-card {
  margin-bottom: 20px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.route-summary {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.route-item {
  text-align: center;
  flex: 1;
}

.route-label {
  font-size: 14px;
  color: #606266;
  margin-bottom: 5px;
}

.route-value {
  font-size: 18px;
  color: #303133;
  font-weight: bold;
}

.route-steps {
  margin-top: 20px;
}

.route-steps h4 {
  margin-bottom: 15px;
  color: #303133;
}

.step-instruction {
  margin: 0;
  color: #303133;
}

.step-distance {
  margin: 5px 0 0 0;
  color: #909399;
  font-size: 12px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .navigation-container {
    padding: 10px;
  }

  .map-container {
    height: 350px;
  }
}
</style>
